package com.example.volunteer.service.impl;


import com.example.volunteer.exception.CustomException;
import com.example.volunteer.mapper.SkillMapper;
import com.example.volunteer.mapper.VolunteerMapper;
import com.example.volunteer.model.Skill;
import com.example.volunteer.model.Volunteer;
import com.example.volunteer.service.VolunteerService;
import com.example.volunteer.util.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;


@Service
public class VolunteerServiceImpl implements VolunteerService {

    @Autowired
    private VolunteerMapper volunteerMapper;

    @Autowired
    private SkillMapper skillMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    @Transactional
    public void register(Volunteer volunteer) {
        if (volunteerMapper.findByEmail(volunteer.getEmail()) != null) {
            throw new CustomException("邮箱已被注册");
        }
        // 加密密码
        String encodedPassword = passwordEncoder.encode(volunteer.getPassword());
        volunteer.setPassword(encodedPassword);
        volunteerMapper.insert(volunteer);
        Volunteer insertedVolunteer = volunteerMapper.findByEmail(volunteer.getEmail());
        if (insertedVolunteer == null) {
            throw new CustomException("注册失败，无法获取志愿者ID");
        }

        // 设置回volunteer对象，供后续技能关联使用
        volunteer.setVolunteerId(insertedVolunteer.getVolunteerId());
        // Add skills
        if (volunteer.getSkills() != null && !volunteer.getSkills().isEmpty()) {
            for (Skill skill : volunteer.getSkills()) {
                Skill existingSkill = skillMapper.findByContent(skill.getSkillContent());
                Integer skillIdToUse;

                if (existingSkill == null) {
                    skillMapper.insert(skill);
                    skillIdToUse = skill.getSkillId();
                } else {
                    skillIdToUse = existingSkill.getSkillId();
                }
                skillMapper.addVolunteerSkill(skillIdToUse, volunteer.getVolunteerId());
            }
        }
        System.out.println("志愿者注册成功 - ID: " + volunteer.getVolunteerId() + ", 姓名: " + volunteer.getName());
    }

    @Override
    public Volunteer findByEmail(String volunteerEmail) {
        return volunteerMapper.findByEmail(volunteerEmail);
    }

    @Override
    @Transactional
    public void update(Volunteer volunteer) {
        Volunteer existing = volunteerMapper.findById(volunteer.getVolunteerId());
        if (existing == null) {
            throw new CustomException("志愿者不存在，无法更新信息");
        }
        // 如果密码有变化，加密新密码
        if (volunteer.getSkills() != null) {
            skillMapper.removeAllVolunteerSkills(volunteer.getVolunteerId());
            for (Skill skill : volunteer.getSkills()) {
                Skill existingSkill = skillMapper.findByContent(skill.getSkillContent());
                Integer skillIdToUse;

                if (existingSkill == null) {
                    skillMapper.insert(skill);
                    skillIdToUse = skill.getSkillId();
                } else {
                    skillIdToUse = existingSkill.getSkillId();
                }
                skillMapper.addVolunteerSkill(skillIdToUse, volunteer.getVolunteerId());
            }
        }
        System.out.println("志愿者信息更新成功 - ID: " + volunteer.getVolunteerId());
    }

    @Override
    public Volunteer findById(String volunteerId) {
        return volunteerMapper.findById(volunteerId);
    }

    @Override
    public void delete(String volunteerId) {
        volunteerMapper.delete(volunteerId);
    }


    @Override
    public PageResult<Volunteer> findVolunteersWithPage(int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        List<Volunteer> volunteers = volunteerMapper.findVolunteersWithPage(offset, pageSize);
        int total = volunteerMapper.countVolunteers();

        PageResult<Volunteer> result = new PageResult<>();
        result.setData(volunteers);
        result.setTotal(total);
        result.setPageNum(pageNum);
        result.setPageSize(pageSize);
        result.setPages((int) Math.ceil((double) total / pageSize));
        return result;
    }

    @Override
    public PageResult<Volunteer> findByIdWithPage(String volunteerId, int pageNum, int pageSize) {
        int offset = calculateOffset(pageNum, pageSize);
        List<Volunteer> volunteers = volunteerMapper.findByIdWithPage(volunteerId, offset, pageSize);
        int total = volunteerMapper.countById(volunteerId);
        return createPageResult(volunteers, total, pageNum, pageSize);
    }

    @Override
    public PageResult<Volunteer> findByNameWithPage(String name, int pageNum, int pageSize) {
        int offset = calculateOffset(pageNum, pageSize);
        List<Volunteer> volunteers = volunteerMapper.findByNameWithPage(name, offset, pageSize);
        int total = volunteerMapper.countByName(name);
        return createPageResult(volunteers, total, pageNum, pageSize);
    }

    @Override
    public PageResult<Volunteer> findByEmailWithPage(String email, int pageNum, int pageSize) {
        int offset = calculateOffset(pageNum, pageSize);
        List<Volunteer> volunteers = volunteerMapper.findByEmailWithPage(email, offset, pageSize);
        int total = volunteerMapper.countByEmail(email);
        return createPageResult(volunteers, total, pageNum, pageSize);
    }

    @Override
    public PageResult<Volunteer> findByContactWithPage(String contact, int pageNum, int pageSize) {
        int offset = calculateOffset(pageNum, pageSize);
        List<Volunteer> volunteers = volunteerMapper.findByContactWithPage(contact, offset, pageSize);
        int total = volunteerMapper.countByContact(contact);
        return createPageResult(volunteers, total, pageNum, pageSize);
    }

    private int calculateOffset(int pageNum, int pageSize) {
        return (pageNum - 1) * pageSize;
    }

    private PageResult<Volunteer> createPageResult(List<Volunteer> data, int total, int pageNum, int pageSize) {
        PageResult<Volunteer> result = new PageResult<>();
        result.setData(data);
        result.setTotal(total);
        result.setPageNum(pageNum);
        result.setPageSize(pageSize);
        result.setPages((int) Math.ceil((double) total / pageSize));
        return result;
    }
}
